﻿using System;
using System.Collections.Generic;
using NHibernate;
using NHibernate.Criterion;
using KKCai.HNKL.Model;
using KKCai.HNKL.Core;

namespace KKCai.HNKL.DAL
{
    public class OmitDao<T> where T : OmitInfo
    {
        protected ISession Session
        {
            get
            {
                return SessionManager.Instance.GetSession();
            }
        }

        public void BeginTransaction()
        {
            SessionManager.Instance.BeginTransaction();
        }

        public void CommitTransaction()
        {
            if (SessionManager.Instance.HasOpenTransaction())
            {
                SessionManager.Instance.CommitTransaction();
            }
        }

        public T Save(T entity)
        {
            Session.Save(entity);
            return entity;
        }

        public IList<T> GetAllObjects()
        {
            return Session.CreateCriteria(typeof(T)).List<T>();
        }

        public IList<T> Order(string propertyName, bool ascending)
        {
            return Session.CreateCriteria(typeof(T))
                .AddOrder(new Order(propertyName, ascending))
                .List<T>();
        }

        public IList<T> Order(string propertyName, bool ascending, int limit)
        {
            return Session.CreateCriteria(typeof(T))
                .AddOrder(new Order(propertyName, ascending))
                .SetMaxResults(limit)
                .List<T>();
        }

        public IList<T> Order(string propertyName, bool ascending, int start, int limit)
        {
            if (start == 0)
            {
                return Order(propertyName, ascending, limit);
            }
            else
            {
                return Session.CreateCriteria(typeof(T))
                    .AddOrder(new Order(propertyName, ascending))
                    //.SetFirstResult(start)
                    //.SetMaxResults(limit)
                    .SetFirstResult(limit)
                    .SetMaxResults(start)
                    .List<T>();
            }
        }




        public virtual IList<T> Search(string key)
        {
            key = key.Replace(" ", "%");

            return Session.CreateCriteria(typeof(T))
                .Add(Expression.Like("Value", key, NHibernate.Criterion.MatchMode.Anywhere))
                .AddOrder(NHibernate.Criterion.Order.Asc("LastID"))
                .List<T>();
        }

        /// <summary>
        /// 根据投注号码查询在某具体玩法下中奖纪录。
        /// </summary>
        protected virtual IList<int> GetIds(string value)
        {
            const string hql = "select r.id from HNKLInfo r where ASC_Result like ?";

            return Session.CreateQuery(hql)
                .SetString(0, MatchMode.Anywhere(value.Replace(" ", "%")))
                .List<int>();
        }

        public void Analyze()
        {
            IList<T> list = this.GetAllObjects();

            foreach (T item in list)
            {
                IList<int> ids = this.GetIds(item.Value);

                if (ids == null || ids.Count == 0)
                    continue;

                AnalyzeResult a = Tools.Analyze(ids);

                item.TotalCount = a.TotalCount;
                item.LastID = a.LastID;
                item.MaxOmit = a.MaxOmit;
                item.MaxOmitQH = Session.Get<HNKLInfo>(a.MaxOmitID).Phase;
            }

            BeginTransaction();
            foreach (T item in list)
            {
                Session.Update(item);
            }
            CommitTransaction();
        }


        /// <summary>
        /// 根据当期开奖结果获得该具体玩法下全部中奖号码
        /// </summary>
        protected virtual IList<T> GetWinCode(HNKLInfo record)
        {
            return null;
        }

        public void UpdateWinOmit(HNKLInfo record)
        {
            IList<T> list = this.GetWinCode(record);

            foreach (T item in list)
            {
                if (item.CurrentOmit > item.MaxOmit)
                {
                    item.MaxOmit = item.CurrentOmit - 1;
                    item.MaxOmitQH = record.Phase;
                }

                item.TotalCount++;
                item.LastID = record.ID;
            }

            BeginTransaction();
            foreach (T item in list)
            {
                Session.Update(item);
            }
            CommitTransaction();
        }

    }
}